﻿package com.rbac.system.service.impl;

import com.rbac.system.service.OnlineUserService;
import com.rbac.system.util.RedisUtil;
import com.rbac.system.vo.OnlineUserVO;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 在线用户服务实现类
 */
@Service
public class OnlineUserServiceImpl implements OnlineUserService {
    
    @Autowired
    private RedisUtil redisUtil;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    private static final String ONLINE_USER_PREFIX = "online_user:";
    private static final String ONLINE_USER_SET = "online_users";
    private static final long ONLINE_USER_EXPIRE = 7200; // 2小时过期
    
    @Override
    public void userOnline(String tokenId, OnlineUserVO userInfo) {
        try {
            String key = ONLINE_USER_PREFIX + tokenId;
            userInfo.setLastAccessTime(LocalDateTime.now());
            
            // 存储用户信息到Redis
            redisUtil.set(key, userInfo, ONLINE_USER_EXPIRE);
            
            // 添加到在线用户集合
            redisUtil.sSet(ONLINE_USER_SET, tokenId);
            redisUtil.expire(ONLINE_USER_SET, ONLINE_USER_EXPIRE);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void userOffline(String tokenId) {
        try {
            String key = ONLINE_USER_PREFIX + tokenId;
            
            // 删除用户信息
            redisUtil.del(key);
            
            // 从在线用户集合中移除
            redisUtil.setRemove(ONLINE_USER_SET, tokenId);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public List<OnlineUserVO> getOnlineUsers() {
        try {
            List<OnlineUserVO> onlineUsers = new ArrayList<>();
            
            // 获取所有在线用户的tokenId
            Set<Object> tokenIds = redisUtil.sGet(ONLINE_USER_SET);
            
            if (tokenIds != null) {
                for (Object tokenId : tokenIds) {
                    String key = ONLINE_USER_PREFIX + tokenId.toString();
                    Object userObj = redisUtil.get(key);
                    
                    if (userObj != null) {
                        try {
                            // 如果是OnlineUserVO对象，直接转换
                            if (userObj instanceof OnlineUserVO) {
                                onlineUsers.add((OnlineUserVO) userObj);
                            } else {
                                // 如果是其他格式，尝试JSON转换
                                String userJson = objectMapper.writeValueAsString(userObj);
                                OnlineUserVO user = objectMapper.readValue(userJson, OnlineUserVO.class);
                                onlineUsers.add(user);
                            }
                        } catch (Exception e) {
                            // 转换失败，从集合中移除这个无效的tokenId
                            redisUtil.setRemove(ONLINE_USER_SET, tokenId);
                        }
                    } else {
                        // 用户信息不存在，从集合中移除
                        redisUtil.setRemove(ONLINE_USER_SET, tokenId);
                    }
                }
            }
            
            return onlineUsers;
            
        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }
    
    @Override
    public void forceLogout(String tokenId) {
        userOffline(tokenId);
    }
    
    @Override
    public void updateLastAccessTime(String tokenId) {
        try {
            String key = ONLINE_USER_PREFIX + tokenId;
            Object userObj = redisUtil.get(key);
            
            if (userObj instanceof OnlineUserVO) {
                OnlineUserVO user = (OnlineUserVO) userObj;
                user.setLastAccessTime(LocalDateTime.now());
                redisUtil.set(key, user, ONLINE_USER_EXPIRE);
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public long getOnlineUserCount() {
        try {
            return redisUtil.sGetSetSize(ONLINE_USER_SET);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    
    @Override
    public boolean isUserOnline(String tokenId) {
        try {
            String key = ONLINE_USER_PREFIX + tokenId;
            return redisUtil.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}


